package com.example.springboot004extensionpoint.applicationListener;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.BootstrapContextClosedEvent;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.event.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.RequestHandledEvent;

@Slf4j
@Component
public class MyApplicationListener {

    /**
     * ApplicationContext 被初始化或刷新时，该事件被发布。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。
     * 此处的初始化是指：所有的Bean被成功装载，后处理Bean被检测并激活，所有Singleton Bean 被预实例化，ApplicationContext容器已就绪可用。
     */
    @EventListener(BootstrapContextClosedEvent.class)
    public void onApplicationEvent(ContextRefreshedEvent event) {
        System.out.println("MyApplicationListener 监听的 ContextRefreshedEvent");
    }

    /**
     *
     * @param event
     */
    @EventListener(ApplicationStartedEvent.class)
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("MyApplicationListener 监听的 ApplicationStartedEvent 事实证明 ApplicationStartedEvent 之后@EventListener 注解才生效");
    }

    @EventListener(ApplicationStartingEvent.class)
    public void onApplicationEvent(ApplicationStartingEvent event) {
        System.out.println("MyApplicationListener 监听的 ApplicationStartingEvent");
    }

    /**
     * 当使用 ConfigurableApplicationContext （ApplicationContext子接口）接口中的 start() 方法启动 ApplicationContext 时，该事件被发布。
     * 你可以调查你的数据库，或者你可以在接受到这个事件后重启任何停止的应用程序。
     */
    @EventListener(ContextStartedEvent.class)
    public void onApplicationEvent(ContextStartedEvent event) {
        System.out.println("MyApplicationListener 监听的  ContextStartedEvent");
    }

    /**
     * 当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时，发布这个事件。
     * 你可以在接受到这个事件后做必要的清理的工作。
     */
    @EventListener(ContextStoppedEvent.class)
    public void onApplicationEvent(ContextStoppedEvent event) {
        System.out.println("MyApplicationListener 监听的  ContextStoppedEvent");
    }

    /**
     * 当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时，该事件被发布。
     * 一个已关闭的上下文到达生命周期末端；它不能被刷新或重启。
     */
    @EventListener(ContextClosedEvent.class)
    public void onApplicationEvent(ContextClosedEvent event) {
        System.out.println("MyApplicationListener 监听的  ContextClosedEvent");
    }

    /**
     * 这是一个 web-specific 事件，告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。
     * 在使用Spring作为前端的MVC控制器时，当Spring处理用户请求结束后，系统会自动触发该事件。
     */
    @EventListener(RequestHandledEvent.class)
    public void onApplicationEvent(RequestHandledEvent event) {
        System.out.println("MyApplicationListener 监听的  RequestHandledEvent");
    }
}
